package org.example.auth.service.impl;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.example.auth.config.AuthParamsConfig;
import org.example.auth.contract.request.UserRequestForCreate;
import org.example.auth.contract.request.UserRequestForUpdatePassword;
import org.example.auth.enums.AuthExceptionEnum;
import org.example.auth.model.entity.User;
import org.example.auth.repository.UserRepository;
import org.example.auth.service.UserRoleService;
import org.example.auth.service.UserService;
import org.example.auth.utils.UserInfoGeneratorUtil;
import org.example.misc.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.transaction.Transactional;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Optional;
import java.util.UUID;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private AuthParamsConfig authParamsConfig;
    @Autowired
    private UserRoleService userRoleService;

    @Override
    public User getUserByIdWithException(Long id) {
        return getUserById(id, true);
    }

    private User getUserById(Long id, Boolean flag) {
        Optional<User> optionalUser = userRepository.findById(id);
        if (optionalUser.isEmpty() && flag) {
            throw new ServiceException("01500", "当前用户不存在");
        }
        return optionalUser.orElse(null);
    }


    @Override
    public User login(String loginName, String password) {
        Optional<User> optionalUser = userRepository.findByLoginNameAndPassword(loginName, encryptPassword(password));
        return optionalUser.orElseThrow(() -> new ServiceException("01500", "用户名密码错误！"));
    }

    @Override
    public List<User> getUserList() {
        return userRepository.findByCommonInfo_EnabledTrue();

    }


    @Override
    @Transactional(rollbackOn = Throwable.class)
    public void updatePassword(UserRequestForUpdatePassword request) {
        Optional<User> optionalUser = userRepository.findByLoginName(request.getLoginName());
        User user = optionalUser.orElseThrow(() -> new ServiceException("01500", "用户名错误！"));
        user.setPassword(encryptPassword(request.getPassword()));
        userRepository.save(user);
    }

    @Override
    @Transactional(rollbackOn = Throwable.class)
    public void deleteUser(Long id) {
        User user = getUserByIdWithException(id);
        userRepository.delete(user);
        //删除用户关联权限
        userRoleService.refreshForDeleteUserId(id);

    }

    @Override
    @Transactional(rollbackOn = Throwable.class)
    public User save(UserRequestForCreate request) {
        // 校验用户登录名是否重复
        Optional<User> optionalUser = userRepository.findByLoginName(request.getLoginName());
        if (optionalUser.isPresent()) {
            throw new ServiceException(AuthExceptionEnum.USER_LOGIN_NAME_EXISTED);
        }

        User user = new User();
        user.setCode(UUID.randomUUID().toString());
        user.setLoginName(request.getLoginName());
        user.setPassword(encryptPassword(request.getPassword()));
        user.setRealName(request.getRealName());
        if (ObjectUtils.isEmpty(request.getNickName())) {
            user.setNickName(UserInfoGeneratorUtil.getRandomName());
        } else {
            user.setNickName(request.getNickName());
        }
        return userRepository.save(user);
    }

    /**
     * 密码加密
     * Base64(password + md5Secret) -> md5
     */
    private String encryptPassword(String password) {
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new ServiceException("01500", "服务异常！");
        }
        return Hex.encodeHexString(md.digest(Base64.decodeBase64(password + authParamsConfig.getMd5Secret())));
    }
}
